namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;
    
	/// <summary>
	/// 1. Starts at Sales homepage
	/// 2. Click on Opportunities
	/// 3. Click New
	/// 4. Add name and Potenial Customer
	/// 5. Click Save & Close
	/// </summary>

    public class CreateNewOpportunity : CrmWebTest
    {
    	public void CreateNewOpportunity_PreWebTest(object sender, PreWebTestEventArgs e)
    	{
			EntityRequest er = new EntityRequest();
			er.Type = EntityNames.Users;
			er.ReturnAs = EntityNames.Users;
			er.ParentID = EntityManager.Instance.OrgId;

			System.Collections.Hashtable Props = new System.Collections.Hashtable();

            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                Props.Add("role", e.WebTest.Context["UserRole"]);
            }
            
			EntityRequest AccountEr = new EntityRequest();
			AccountEr.Type = EntityNames.Accounts;
			AccountEr.ParentID = Guid.NewGuid();
			AccountEr.ReturnAs = EntityNames.Accounts;

			Props.Add(EntityNames.Accounts, new EntityRequest[] { AccountEr });

			er.Props = Props;

			System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

			user = (CRMEntity)Entities[EntityNames.Users];
			customer = (CRMEntity)Entities[EntityNames.Accounts];
            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);

            orgId = new Guid(user["organizationid"]);

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];            
    	}

    	public void CreateNewOpportunity_PostWebTest(object sender, PostWebTestEventArgs e)
    	{
			try
			{
                if (newOpportunityId != null)
                {
                    newOpportunityId = new Guid(newOpportunityId).ToString();
                    Guid g = EntityManager.Instance.GetOwnerGuid(new Guid(user[EntityIDNames.User]), new Guid(user["OrganizationId"]));
                    EntityManager.Instance.AddEntity(EntityNames.Opportunities, g, new string[] { "OwningUser", "OpportunityID", "EntityManagerOwningUser" }, new string[] { user["systemuserid"], newOpportunityId , g.ToString()});
                }
			}
            catch (System.FormatException fe)
            {
                System.Diagnostics.Trace.WriteLine("OpportunityId should never be set to anything other than Guid. This should not happen. " + fe.ToString());
            }
			finally
			{
				EntityManager.Instance.FreeEntity(user);
				EntityManager.Instance.FreeEntity(customer);
			}
    	}

		private void NewAnnotation_ValidateResponse(object sender, ValidationEventArgs e)
		{
			string ID = null;

			int idIdx = e.Response.BodyString.IndexOf(newIdMarker);
			ID = e.Response.BodyString.Substring(idIdx + (CreateNewOpportunity.newIdMarker.Length), 36);
			try
			{
				ID = new Guid(ID).ToString();
			}
			catch (System.FormatException fe)
			{
				System.Diagnostics.Trace.WriteLine("Format exception: " + fe.ToString());
				e.IsValid = false;
				return;
			}
			e.IsValid = true;
		}

    	public CreateNewOpportunity()
    	{
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            GetContextHtml_Helper.PriceList(out ctxt, out ctxt_formXml, out ctxt_formSubmitId);

            gridXml = GridXmlHelper.OpportunityPageViewRefresh(-1, myOpenOpportunitiesView, null);

    		this.Proxy = null;            
    		PreWebTest += new EventHandler<PreWebTestEventArgs>(CreateNewOpportunity_PreWebTest);
    		PostWebTest += new EventHandler<PostWebTestEventArgs>(CreateNewOpportunity_PostWebTest);
    	}

    	public override IEnumerator<WebTestRequest> GetRequestEnumerator()
    	{
            this.BeginTransaction("NavOpportunityHomepage");

            _root_homepage_aspx hp = new _root_homepage_aspx(user);
    		hp.etc = 3;
    		yield return (hp);

            this.EndTransaction("NavOpportunityHomepage");
			
			this.BeginTransaction("CreateOpportunity");

            sfa_opps_edit_aspx dp = new sfa_opps_edit_aspx(user);
    		yield return (dp);

            referer = dp.lastResponse.ResponseUri.AbsoluteUri;

            _forms_FormScript_js_aspx f = new _forms_FormScript_js_aspx(user);
            f.etc = 3;
            f.FormType = "main";
            f.FormName = "crmForm";
            headerItem = new WebTestRequestHeader("referer", referer);
            f.Headers.Add(headerItem);
            yield return (f);

            _controls_lookup_lookupsingle_aspx ls = new _controls_lookup_lookupsingle_aspx(user);
			ls.Class = "BasicCustomer";
			ls.objecttypes = "1,2";
			ls.browse = 0;
            ls.ShowNewButton = 1;
            ls.ShowPropButton = 1;
			ls.DefaultType = 0;
			yield return (ls);

    		// if the Help and Assistance Pane is on and the user tabs through the fields of the Opportunity
    		// detail pane, they'll hit this (heavy) request when the tab into the 
    		// price list field.
    		if (ConfigSettings.Default.HelpAndAssistancePaneOn == "true")
    		{
 				RelatedInformation.RelatedInformation ri = new RelatedInformation.RelatedInformation();
    			WebTestRequest wtr = null;

    			try { ri.GetContextHtml(ctxt, ctxt_formXml, ctxt_formSubmitId); }
    			catch (crmException x)
    			{
    				wtr = (CrmRequest)x.wtr;
                    wtr.Url = Utils.ReplaceServerName(wtr.Url, user);

                    string urlPath = wtr.Url.Remove(0, crmServer.Length);
                    urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                    rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                    headerItem = new WebTestRequestHeader();
                    headerItem.Name = "crmwrpctokentimestamp";
                    headerItem.Value = rpcInfo.timeStamp.ToString();
                    wtr.Headers.Add(headerItem);
                    headerItem = new WebTestRequestHeader();
                    headerItem.Name = "crmwrpctoken";
                    headerItem.Value = rpcInfo.token;
                    wtr.Headers.Add(headerItem);
                    wtr.Method = "Post";
    			}
    			yield return (wtr);
    		}
            
            dp = new sfa_opps_edit_aspx(user);
            name = Utils.GetRandomString(5,10);
            dp.crmFormSubmitXml = EntityXmlHelper.GetCreateOpportunityXml(new Guid(user["SystemUserId"]), 8, name, new Guid(customer["accountid"]),1); //obj.Serialize();

            rpcInfo = Utils.GenerateWRPCToken(sfa_opps_edit_aspx.url, user, tokenKey);
    		dp.CRMWRPCToken = rpcInfo.token;
    		dp.CRMWRPCTokenTimeStamp = rpcInfo.timeStamp;
    		dp.crmFormSubmitMode = 1;
    		dp.crmFormSubmitObjectType = 3;
            dp.crmFormUserModified = true;
    		dp.crmFormSubmitSecurity = 852023;
    		dp.crmFormSubmitOnline = 1;
			dp.ValidateResponse += this.NewAnnotation_ValidateResponse;
    		yield return (dp);

    		//get the newly created Opportunity id out of the post reply
    		int idIdx = dp.lastResponse.BodyString.IndexOf(newIdMarker);
 			string tempNewOpportunityId = dp.lastResponse.BodyString.Substring(idIdx + (CreateNewOpportunity.newIdMarker.Length), 36);
			newOpportunityId = new Guid(tempNewOpportunityId).ToString();

 			AppGridWebService.AppGridWebService agws = new AppGridWebService.AppGridWebService();
    		WebTestRequest wtrRefresh = null;
            try { agws.Refresh(gridXml); }
    		catch (crmException x)
    		{
    			wtrRefresh = x.wtr;
                wtrRefresh.Url = Utils.ReplaceServerName(wtrRefresh.Url, user);

                string urlPath = wtrRefresh.Url.Remove(0, crmServer.Length);
                urlPath = urlPath.Remove(0, user["organizationName"].Length + 1);

                rpcInfo = Utils.GenerateWRPCToken(urlPath, user, tokenKey);

                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctokentimestamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                wtrRefresh.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "crmwrpctoken";
                headerItem.Value = rpcInfo.token;
                wtrRefresh.Headers.Add(headerItem);
                wtrRefresh.Method = "Post";
    		}
    		yield return (wtrRefresh);

			this.EndTransaction("CreateOpportunity");
    	}

        private const string newIdMarker = @"separator + ""id=";
    	private CRMEntity user, customer;
  		private static RelatedInformation.Context ctxt;
    	private static string ctxt_formXml;
    	private static string ctxt_formSubmitId;
 		private string newOpportunityId;
        private string gridXml;
        private string crmServer;
        private string tokenKey;
        private static string myOpenOpportunitiesView = "00000000-0000-0000-00AA-000010003000";

        private Guid orgId;
        private string name;

        private string referer;
        private WRPCInfo rpcInfo;
        private WebTestRequestHeader headerItem;
    }
}